
import md5 from 'js-md5'
import NP from 'number-precision'

/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string | null}
 */
export function parseTime(time, cFormat) {
  if (arguments.length === 0 || !time) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if ((typeof time === 'string')) {
      if ((/^[0-9]+$/.test(time))) {
        // support "1548221490638"
        time = parseInt(time)
      } else {
        // support safari
        // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
        time = time.replace(new RegExp(/-/gm), '/')
      }
    }

    if ((typeof time === 'number') && (time.toString().length === 10)) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
    const value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] }
    return value.toString().padStart(2, '0')
  })
  return time_str
}

/**
 * @param {number} time
 * @param {string} option
 * @returns {string}
 */
export function formatTime(time, option) {
  if (('' + time).length === 10) {
    time = parseInt(time) * 1000
  } else {
    time = +time
  }
  const d = new Date(time)
  const now = Date.now()

  const diff = (now - d) / 1000

  if (diff < 30) {
    return '刚刚'
  } else if (diff < 3600) {
    // less 1 hour
    return Math.ceil(diff / 60) + '分钟前'
  } else if (diff < 3600 * 24) {
    return Math.ceil(diff / 3600) + '小时前'
  } else if (diff < 3600 * 24 * 2) {
    return '1天前'
  }
  if (option) {
    return parseTime(time, option)
  } else {
    return (
      d.getMonth() +
      1 +
      '月' +
      d.getDate() +
      '日' +
      d.getHours() +
      '时' +
      d.getMinutes() +
      '分'
    )
  }
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function getQueryObject(url) {
  url = url == null ? window.location.href : url
  const search = url.substring(url.lastIndexOf('?') + 1)
  const obj = {}
  const reg = /([^?&=]+)=([^?&=]*)/g
  search.replace(reg, (rs, $1, $2) => {
    const name = decodeURIComponent($1)
    let val = decodeURIComponent($2)
    val = String(val)
    obj[name] = val
    return rs
  })
  return obj
}

/**
 * @param {string} input value
 * @returns {number} output value
 */
export function byteLength(str) {
  // returns the byte length of an utf8 string
  let s = str.length
  for (var i = str.length - 1; i >= 0; i--) {
    const code = str.charCodeAt(i)
    if (code > 0x7f && code <= 0x7ff) s++
    else if (code > 0x7ff && code <= 0xffff) s += 2
    if (code >= 0xDC00 && code <= 0xDFFF) i--
  }
  return s
}

/**
 * @param {Array} actual
 * @returns {Array}
 */
export function cleanArray(actual) {
  const newArray = []
  for (let i = 0; i < actual.length; i++) {
    if (actual[i]) {
      newArray.push(actual[i])
    }
  }
  return newArray
}

/**
 * @param {Object} json
 * @returns {Array}
 */
export function param(json) {
  if (!json) return ''
  return cleanArray(
    Object.keys(json).map(key => {
      if (json[key] === undefined) return ''
      return encodeURIComponent(key) + '=' + encodeURIComponent(json[key])
    })
  ).join('&')
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function param2Obj(url) {
  const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
  if (!search) {
    return {}
  }
  const obj = {}
  const searchArr = search.split('&')
  searchArr.forEach(v => {
    const index = v.indexOf('=')
    if (index !== -1) {
      const name = v.substring(0, index)
      const val = v.substring(index + 1, v.length)
      obj[name] = val
    }
  })
  return obj
}

/**
 * @param {string} val
 * @returns {string}
 */
export function html2Text(val) {
  const div = document.createElement('div')
  div.innerHTML = val
  return div.textContent || div.innerText
}

/**
 * Merges two objects, giving the last one precedence
 * @param {Object} target
 * @param {(Object|Array)} source
 * @returns {Object}
 */
export function objectMerge(target, source) {
  if (typeof target !== 'object') {
    target = {}
  }
  if (Array.isArray(source)) {
    return source.slice()
  }
  Object.keys(source).forEach(property => {
    const sourceProperty = source[property]
    if (typeof sourceProperty === 'object') {
      target[property] = objectMerge(target[property], sourceProperty)
    } else {
      target[property] = sourceProperty
    }
  })
  return target
}

/**
 * @param {HTMLElement} element
 * @param {string} className
 */
export function toggleClass(element, className) {
  if (!element || !className) {
    return
  }
  let classString = element.className
  const nameIndex = classString.indexOf(className)
  if (nameIndex === -1) {
    classString += '' + className
  } else {
    classString =
      classString.substr(0, nameIndex) +
      classString.substr(nameIndex + className.length)
  }
  element.className = classString
}

/**
 * @param {string} type
 * @returns {Date}
 */
export function getTime(type) {
  if (type === 'start') {
    return new Date().getTime() - 3600 * 1000 * 24 * 90
  } else {
    return new Date(new Date().toDateString())
  }
}

/**
 * @param {Function} func
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
export function debounce(func, wait, immediate) {
  let timeout, args, context, timestamp, result

  const later = function() {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp

    // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last)
    } else {
      timeout = null
      // 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args)
        if (!timeout) context = args = null
      }
    }
  }

  return function(...args) {
    context = this
    timestamp = +new Date()
    const callNow = immediate && !timeout
    // 如果延时不存在，重新设定延时
    if (!timeout) timeout = setTimeout(later, wait)
    if (callNow) {
      result = func.apply(context, args)
      context = args = null
    }

    return result
  }
}

/**
 * This is just a simple version of deep copy
 * Has a lot of edge cases bug
 * If you want to use a perfect deep copy, use lodash's _.cloneDeep
 * @param {Object} source
 * @returns {Object}
 */
export function deepClone(source) {
  if (!source && typeof source !== 'object') {
    throw new Error('error arguments', 'deepClone')
  }
  const targetObj = source.constructor === Array ? [] : {}
  Object.keys(source).forEach(keys => {
    if (source[keys] && typeof source[keys] === 'object') {
      targetObj[keys] = deepClone(source[keys])
    } else {
      targetObj[keys] = source[keys]
    }
  })
  return targetObj
}

/**
 * @param {Array} arr
 * @returns {Array}
 */
export function uniqueArr(arr) {
  return Array.from(new Set(arr))
}

/**
 * @returns {string}
 */
export function createUniqueString() {
  const timestamp = +new Date() + ''
  const randomNum = parseInt((1 + Math.random()) * 65536) + ''
  return (+(randomNum + timestamp)).toString(32)
}

/**
 * Check if an element has a class
 * @param {HTMLElement} elm
 * @param {string} cls
 * @returns {boolean}
 */
export function hasClass(ele, cls) {
  return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'))
}

/**
 * Add class to element
 * @param {HTMLElement} elm
 * @param {string} cls
 */
export function addClass(ele, cls) {
  if (!hasClass(ele, cls)) ele.className += ' ' + cls
}

/**
 * Remove class from element
 * @param {HTMLElement} elm
 * @param {string} cls
 */
export function removeClass(ele, cls) {
  if (hasClass(ele, cls)) {
    const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)')
    ele.className = ele.className.replace(reg, ' ')
  }
}


/**
 * 获取当前登录用户信息
 * */
export function getUserInfo() {
  return JSON.parse(localStorage.getItem('USER_INFO'))
}

/**
* 获取当前身份验证key
*/
export function getKey() {
  let key = ''
  if (process.env.VUE_APP_API_KEY) { // 开发环境 测试key
      key = process.env.VUE_APP_API_KEY
  } else {
      const date = new Date()
      date.setSeconds(0)
      date.setMilliseconds(0)
      key = md5(process.env.VUE_APP_PROJECT_KEY +
              process.env.VUE_APP_SECRET_KEY +
              (date / 1000)) +
          process.env.VUE_APP_COMPANY_ID
  }

  return key
}

/**
* 获取本月第一天时间对象
*/
export function getFirstDate() {
  const date = new Date(new Date().toDateString())
  date.setDate(1)

  return date
}

/**
* 获取前/后若干月时间对象
* @param { Number } range 距离当前。0表示当前月，正数表示当前之后某月（如1表示下个月），负数表示当前之前某月（如-1表示上个月）
* @return { Date } date 时间对象
*/
export function getMonthDate(range = 0) {
  const date = new Date(new Date().toDateString())
  date.setDate(1) // 设置日期 1~31
  date.setMonth(date.getMonth() + range) // 0~11 0表示1月

  return date
}

/**
* 获取指定时间对象数据
*/
export function getDateArr(type = 'week', num = 0) {
  const start = new Date(new Date().toDateString())
  const end = new Date(new Date().toDateString())
  if (type === 'today') { // 当天
      end.setTime(start.getTime() + 3600 * 1000 * 24 - 1)
  } else if (type === 'week') { // 本周
      start.setTime(start.getTime() + 3600 * 1000 * 24 * (1 - start.getDay()))
      end.setTime(start.getTime() + 3600 * 1000 * 24 * 7 - 1)
  } else if (type === 'month') { // 本月
      start.setDate(1)
      end.setDate(1)
      end.setMonth(end.getMonth() + 1)
      end.setTime(end.getTime() - 1)
  } else if (type === 'year') { // 本年
      start.setDate(1)
      start.setMonth(0)
      end.setDate(1)
      end.setMonth(12)
      end.setTime(end.getTime() - 1)
  } else if (type === 'last_year') { // 去年
      start.setDate(1)
      start.setMonth(-12)
      end.setDate(1)
      end.setMonth(0)
      end.setTime(end.getTime() - 1)
  } else if (type === 'recent_week') { // 近一周
      start.setDate(start.getDate() - 7)
      end.setDate(end.getDate() + 1)
      end.setTime(end.getTime() - 1)
  } else if (type === 'lately') { // 近N天
      start.setDate(start.getDate() - num)
  } else if (type === 'tq') { // 本季度
      start.setDate(1)
      start.setMonth(Math.floor(start.getMonth() / 3) * 3)
      end.setDate(1)
      end.setMonth(start.getMonth() + 3)
      end.setTime(end.getTime() - 1)
  } else if (type === 'q1') { // 第一季度
      start.setDate(1)
      start.setMonth(0)
      end.setDate(1)
      end.setMonth(3)
      end.setTime(end.getTime() - 1)
  } else if (type === 'q2') { // 第二季度
      start.setDate(1)
      start.setMonth(3)
      end.setDate(1)
      end.setMonth(6)
      end.setTime(end.getTime() - 1)
  } else if (type === 'q3') { // 第三季度
      start.setDate(1)
      start.setMonth(6)
      end.setDate(1)
      end.setMonth(9)
      end.setTime(end.getTime() - 1)
  } else if (type === 'q4') { // 第四季度
      start.setDate(1)
      start.setMonth(9)
      end.setDate(1)
      end.setMonth(12)
      end.setTime(end.getTime() - 1)
  }

  return [start, end]
}

/**
* 移除指定对象，其属性中值为空的属性
* @param { Object } obj 目标对象
* @param { Array } properties 属性数组
* @param { Array } targets 目标值数组，值等于于其中的一个视为符合移除条件
*/
export function deleteNullProperty(obj, properties, targets = []) {
  if (!(properties instanceof Array)) {
      throw new Error('参数错误，应为Array类型')
  }
  if (targets.length === 0) {
      properties.forEach((property) => {
          if (obj[property]) {
              delete obj[property]
          }
      })
  } else {
      const keys = Object.keys(obj)
      properties.forEach((property) => {
          if (keys.includes(property) && targets.includes(obj[property])) {
              delete obj[property]
          }
      })
  }
}

/**
* 移除指定对象指定属性
* @param { Object } obj 目标对象
* @param { Array } properties 属性数组
*/
export function deleteProperty(obj, properties) {
  if (!(properties instanceof Array)) {
      throw new Error('参数错误，应为Array类型')
  }
  properties.forEach((property) => {
      delete obj[property]
  })
}

/**
* 字符串转换
* @param { String } str 转换字符串
* @param { Array } targets 匹配字符串数组
* @param { String } replacement
*/
export function replaceAll(str, targets, replacement = '') {
  targets.forEach((target) => {
      str = str.replaceAll(target, replacement)
  })

  return str
}

/**
* 格式化数字
* @param { Number } str 数字
*/
export function numberFormat(num) {
  if (typeof (num) === 'undefined' || num === '' || num === null || Number.isNaN(num)) {
      return
  }
  const res = num.toString().replace(/\d+/, function(n) {
      return n.replace(/(\d)(?=(\d{3})+$)/g, function($1) {
          return $1 + ','
      })
  })

  return res
}

/**
* inArray
*/
export function inArray(arr, sub) {
  const res = arr.filter(v => {
      return v === sub
  })
  return (res.length > 0)
}

/**
* 引入百度地图API
*/
export function loadBMap(ak) {
  return new Promise((resolve, reject) => {
      if (typeof window.BMap !== 'undefined') {
          resolve(window.BMap)
      }
      window.onBMapCallback = function() {
          resolve(window.BMap)
      }
      const script = document.createElement('script')
      script.type = 'text/javascript'
      script.src = `https://api.map.baidu.com/api?v=3.0&ak=${ak}&callback=onBMapCallback`
      script.onerror = reject
      document.head.appendChild(script)
  })
}

/**
* 处理数据，取出数据及其从属数据的指定属性
*/
export function handleDataChildrens(data, label, value, fn) {
  const list = []
  data.forEach(item => {
      if (!fn || fn(item)) {
          list.push({ label: item[label], value: value ? item[value] : item })
      }
      if (item.children) {
          list.push(...handleDataChildrens(item.children, label, value))
      } else if (item.childrens) {
          list.push(...handleDataChildrens(item.childrens, label, value))
      }
  })

  return list
}

/**
* 处理搜索参数
*/
export function handleSearchParams(params, callback) {
  for (const key in params) {
      if (params[key] === '' || params[key] === undefined) {
          delete params[key]
      } else if (params[key] instanceof Object) {
          params[key] = handleSearchParams(params[key])
      }
  }
  if (callback) {
      callback(params)
  }

  return params
}

/**
* 校验货币数字
* minus 是否允许负数
*/
export function checkCurrency(value, minus = false) {
  if (minus) {
      return new RegExp('(^-?[1-9]\\d*(\\.\\d{1,2})?$)|(^-?0(\\.\\d{1,2})?$)').test(value)
  } else {
      return new RegExp('(^[1-9]\\d*(\\.\\d{1,2})?$)|(^0(\\.\\d{1,2})?$)').test(value)
  }
}

/**
* 货币数字单位换算
*/
export function convertCurrency(value, min = true) {
  if (!value) {
      return value
  }
  if (min) { // 将数值转换至最小单位表示
      return NP.times(value, 100)
  } else {
      return NP.divide(value, 100)
  }
}

/**
* 处理重量单位换算
*/
export function convertWeight(value, unit = 't', min = true) {
  if (!value) {
      return value
  }
  const lb = 453.59237
  if (min) { // 将数值转换至最小单位表示
      let newValue = value
      if (['t', '吨'].includes(unit)) {
          newValue = NP.times(value, 1000, 1000)
      } else if (['kg', '千克', 'l', '升'].includes(unit)) {
          newValue = NP.times(value, 1000)
      } else if (['lb', '磅'].includes(unit)) {
          newValue = NP.times(value, lb)
      }

      return Math.ceil(newValue)
  } else { // 数值是最小单位，转换至指定单位表示
      let newValue = value
      if (['t', '吨'].includes(unit)) {
          newValue = NP.divide(value, 1000, 1000)
      } else if (['kg', '千克', 'l', '升'].includes(unit)) {
          newValue = NP.divide(value, 1000)
      } else if (['lb', '磅'].includes(unit)) {
          newValue = NP.divide(value, lb)
      }

      return newValue
  }
}

/**
* 处理每吨价格 / (单位)单价
* @param { Number } price （单位）单价 / 每吨价格
* @param { Number } unitWeight 每单位重量（克）
* @param { Number } t 是否要换算为每吨价格，true 将价格换算为每吨价格，此时price代表（单位）单价； false 将价格换算为（单位）单价，此时price代表每吨价格
* @returns { Number } 每吨价格 /（单位）单价
*/
export function convertTonPrice(price, unitWeight, t = true) {
  const num = NP.divide(1000000, +unitWeight)
  if (t === true) {
      return Math.round(NP.times(num, +price)) // = num * price
  } else {
      return NP.divide(+price, num) // = price / num
  }
}

/**
* 处理企业筛选数据（接口apiCustomer.getList / apiCustomer.searchList）
*/
export function handleCompanyData(res, fields = []) {
  let list = []
  if (!res.data) {
      return list
  }
  if (res.data.data) {
      list = res.data.data
  } else if (res.data.list instanceof Array) {
      list = res.data.list
  } else if (res.data.list && res.data.list.data instanceof Array) {
      list = res.data.list.data
  }

  return list.map(item => {
      const result = { label: item.name, value: item.id }
      if (fields.length > 0) {
          fields.forEach(key => {
              result[key] = item[key]
          })
      }

      return result
  })
}

/**
* 处理多选内容空值、重复值检测
*/
export function handleCheckOptionsValue(targetObj, callback, checkRepeat = true) {
  if (!targetObj.hidden) {
      // 是否有空值
      targetObj.value.some(item => {
          if (item.label === '' || item.value === '') {
              callback('请输入完整')
              return true
          }
      })
      if (checkRepeat) {
          // 是否有重复值
          const valueList = targetObj.value.map(item => {
              return item.value
          })
          const valueSet = new Set(valueList)
          if (valueList.length !== valueSet.size) {
              callback('检测到重复值，请更改')
          }
      }
  }
  callback()
}

/**
* 处理表单选项数据
*/
export function handleFormOptions(value) {
  if (!value) return []
  let result = []
  try {
      if (value instanceof Array) {
          result = value
      } else if (value && typeof value === 'string') {
          value = value.replace(/\\/g, '')
          value = value.replace(/\"{/g, '{')
          value = value.replace(/\"\[/g, '[')
          value = value.replace(/\}"/g, '}')
          value = value.replace(/\]"/g, ']')
          result = JSON.parse(value)
      }
  } catch (e) {
      console.log(e)
  }

  return result
}

/**
* 处理表单组件状态（显示/隐藏）控制
*/
export function handleFieldControl(fieldObj, source) {
  const value = fieldObj[source].value
  for (const key in fieldObj[source].control) {
      fieldObj[key].hidden = !fieldObj[source].control[key].show_val.split('|').includes(value)
  }
}

/**
* 获取指定 label
*/
export function getLabel(list, value) {
  let label = ''
  list.some(item => {
      if (item.value === value) {
          label = item.label
          return true
      }
  })

  return label
}

/**
* 从数组中获取指定对象
*/
export function getObj(list, key, keyVal) {
  let obj = null
  list.some((item) => {
      if (item[key] === keyVal) {
          obj = item
          return true
      }
  })
  return obj
}

/**
* 获取筛选项信息
*/
export function getSearchFields(search_fields) {
  const options = []
  for (const key in search_fields) {
      if (key !== 'fields' && !search_fields[key].hidden) {
          options.push({
              label: search_fields[key].label,
              value: key
          })
      }
  }

  return options
}

/**
* 处理规格信息
*/
export function handleSpecDesc(attrs) {
  if (typeof attrs === 'string' && attrs.length > 0) {
      attrs = JSON.parse(attrs)
  }
  if (!(attrs instanceof Array)) return ''
  return attrs.map(item => {
      if (item.label === 'type') {
          return `型号：${item.title}`
      } else if (item.label === 'standards') {
          return `规格：${item.title}`
      } else {
          return item.title
      }
  }).join(',')
}

/**
* 处理企业同事头像
*/
export function handleAvatar(avatar) {
  if (avatar === '/images/avatar/default.png' || avatar === '' || avatar === null) {
      return 'http://iph.href.lu/90x90'
  } else if (avatar.indexOf('/storage') === 0) {
      return process.env.VUE_APP_BASE_API.split('api/')[0] + avatar.slice(1)
  } else if (avatar.indexOf('http') === -1 && avatar.indexOf('//') === -1) {
      return '//' + avatar
  } else {
      return avatar
  }
}

/**
* 处理表单空值字段，部分提交表单的接口参数需要用到
*/
export function handleEmptyValue(params, emptyList = ['', undefined]) {
  for (const key in params) {
      if (emptyList.includes(params[key])) {
          delete params[key]
      }
  }

  return params
}

/**
* 获取拓展字段
*/
export function getExtValue(exts, name) {
  if (!(exts instanceof Array)) return ''
  let result = ''
  exts.some(item => {
      if (item.name === name) {
          result = item.content
          return true
      }
  })
  return result
}

/**
* 获取运单数据字段的值（原订单扩展字段）
*/
export function getWaybillValue(waybill, name) {
  if (!waybill) return ''
  let result = ''
  if (waybill[name] !== null) {
      result = waybill[name]
  }
  return result
}

/**
* 获取签收单数据
*/
export function getReceiptData(waybill, _this) {
  const path = getWaybillValue(waybill, 'receipt_image')
  if (path === '') return []
  return handleFilePath(path, _this, true)
}

/**
* 处理拓展字段，用于详情页展示
*/
export function handleExt(exts, _this = null) {
  const list = []
  exts.forEach(item => {
      if (item.name === 'credit_customer_state') return
      const ext = { label: item.label, value: item.content }
      if (item.content instanceof Array) {
          ext.type = 'files'
          ext.previewList = []
          ext.value = item.content.map(file => {
              if (['jpg', 'jpeg', 'png', 'bmp', 'gif'].includes(file.suffix)) {
                  file.type = 'image'
                  ext.previewList.push(file.path)
              } else {
                  file.type = 'file'
              }

              return file
          })
      } else if (item.content && item.content.indexOf('/storage') === 0) {
          ext.type = 'files'
          ext.previewList = []
          const filePaths = handleFilePath(item.content, _this, true)
          ext.value = filePaths.map(file => {
              const suffix = file.path.substring(file.path.lastIndexOf('.') + 1)
              if (['jpg', 'jpeg', 'png', 'bmp', 'gif'].includes(suffix)) {
                  file.type = 'image'
                  ext.previewList.push(file.path)
              } else {
                  file.type = 'file'
              }

              return file
          })
      } else if (checkFilesType(item.detail.type, 'options') && item.detail.options) {
          ext.value = getLabel(item.detail.options, item.content)
      }
      list.push(ext)
  })

  return list
}

/**
* 处理订单状态描述
*/
export function handleOrderDesc(code, orderDescList, status) {
  const lastCode = Number(String(code).split('').reverse()[0])
  if (lastCode === 0) {
      return getLabel(orderDescList, code)
  } else if (lastCode === 1) {
      return '订单已完成'
  } else if (lastCode === 2) {
      return '订单已取消'
  } else if (lastCode === 3) {
      if (status === 'success') {
          return '订单已完成'
      } else {
          return getLabel(orderDescList, code.slice(0, -1).replace(/$/, '0'))
      }
  }
}

/**
* 检查附件类型
*/
export function checkFilesType(value, type) {
  if (type === 'file') {
      return ['fileupload', 'imageupload', 'videoupload', 'file', 'image', 'video'].includes(value)
  } else if (type === 'files') {
      return ['filesupload', 'imagesupload', 'videosupload', 'files', 'images', 'videos'].includes(value)
  } else if (type === 'date') {
      return ['datepicker', 'timepicker', 'date', 'time'].includes(value)
  } else if (type === 'options') {
      return ['select', 'switch', 'checkbox', 'radio'].includes(value)
  } else if (type === 'text') {
      return ['text', 'textarea'].includes(value)
  } else {
      return false
  }
}

/**
* 处理审批流程，移除发起人
*/
export function handleAuditors(auditors, uid) {
  let opinion = ''
  auditors.some((item, index) => {
      if (item.uid.toString() === uid.toString() && item.status === 'resolve') {
          // 如果前一个不是转交审批
          if (index > 0 && auditors[index - 1].status !== 'transto') {
              auditors.splice(index, 1)
              opinion = '用户发起自行通过'
              return true
          }
      }
  })
  return { auditors, opinion }
}

/**
* 处理审批表单数据
*/
export function handleAuditFormData(row, isAudit) {
  let form_title = ''
  if (row.form) {
      form_title = row.form.label
  } else {
      form_title = row.meta.name
  }
  let title = ''
  if (isAudit) {
      title = '审批 - ' + form_title
  } else {
      title = form_title + ' - 详情'
  }

  return {
      id: row.id,
      created_at: row.created_at,
      form_id: row.form_id,
      title,
      form_title
  }
}

/**
* 处理审批字段数据
*/
export function handleFieldData(field, formFields = null, _this = null) {
  if (field.type === 'divider') return
  if (formFields) {
      formFields.some(item => {
          if (item.id.toString() === field.field_id.toString()) {
              Object.assign(field, item)
              return true
          }
      })
  }
  if (['switch', 'select', 'checkbox', 'radio'].includes(field.type) && field.value !== '') {
      let value = field.value
      let newValue = ''
      if (!(value instanceof Array)) {
          value = String(value).split(',')
      }
      newValue = value.map(v => {
          let result = ''
          field.options.some(o => {
              if (v === o.value.toString()) {
                  result = o.label
                  return true
              }
          })
          return result
      }).join(',')
      field.value = newValue
  } else if (field.type === 'datepicker' && field.value) {
      field.value = field.value.split(' ')[0]
  } else if (field.type === 'timepicker' && field.value) {
      field.value = field.value.split(' ')[1]
  } else if (field.value && field.value instanceof Object) {
      if (field.value.type === 'custom_table') {
          field.type = 'custom-data'
          field.custom = {
              type: 'custom-table',
              keys: Object.keys(field.value.value[0]),
              value: field.value.value.map((item) => {
                  Object.keys(item).forEach(key => {
                      const value = item[key]
                      if (/^\[:{1}\S+:\]{1}$/.test(value)) {
                          item[key] = value.substring(2, value.length - 2).split('|')
                      }
                  })
                  return item
              })
          }
      }
  } else if (field.value && field.value.toString().indexOf('{"type"') === 0) {
      const data = JSON.parse(field.value)
      if (data.type === 'custom_table') {
          field.type = 'custom-data'
          field.custom = {
              type: 'custom-table',
              keys: Object.keys(data.value[0]),
              value: data.value.map((item) => {
                  Object.keys(item).forEach(key => {
                      const value = item[key]
                      if (/^\[:{1}\S+:\]{1}$/.test(value)) {
                          item[key] = value.substring(2, value.length - 2).split('|')
                      }
                  })
                  return item
              })
          }
      }
  } else if (field.value && /^\[:{1}\S+:\]{1}$/.test(field.value)) {
      const params = field.value.substring(2, field.value.length - 2).split('|')
      field.type = 'sys-custom'
      field.custom = {
          type: params[0],
          value: params[1],
          label: params[2]
      }
      if (params.length > 3) {
          field.custom_more = {
              type: field.custom.type,
              value: params[3],
              label: params[4]
          }
      }
      if (field.custom.type === 'attachment') {
          field.custom.value = handleFilePath(field.custom.value, _this, true).map(item => item.path)
          if (field.custom_more) {
              field.custom.value.push(...handleFilePath(field.custom_more.value, _this, true).map(item => item.path))
          }
      }
      if (field.custom.type === 'current_overdue') {
          field.custom.value = JSON.parse(field.custom.value).buyer_company_id
      }
      if (field.custom.type === 'batch_info') {
          const value = JSON.parse(field.custom.value)
          field.custom.value = value
          // 处理发货信息描述
          let desc = ''
          value.forEach((item, index) => {
              const batch_name = item.no_type === 'batch_no' ? '批次号' : '柜号'
              if (index > 0) {
                  desc += '。'
              }
              const total = convertWeight(NP.times(item.weight, item.out_qty), 't', false)
              desc += `从${item.warehouse}发出${total}吨，`
              item.contract_batch.forEach((c, cIndex) => {
                  if (cIndex > 0) {
                      desc += '；'
                  }
                  desc += `合同号${c.contract_no}，`
                  c.batch_info.forEach((info, i) => {
                      const weight = convertWeight(NP.times(item.weight, info.qty), 't', false)
                      if (i > 0) {
                          desc += '，'
                      } else {
                          desc += '其中'
                      }
                      desc += `${info.no}（${batch_name}）发${weight}吨`
                  })
              })
              if (index === value.length - 1) {
                  desc += '。'
              }
          })
          field.custom.desc = desc
      }
  } else if (['imagesupload', 'filesupload', 'videosupload', 'imageupload', 'fileupload', 'videoupload'].includes(field.type)) {
      field.type = 'sys-custom'
      field.custom = {
          type: 'attachment',
          value: field.value ? field.value.split(',') : []
      }
  }
}

/**
* 获取路由中的id
*/
export function getPathId(_this) {
  return _this.$route.path.split('/').reverse()[0]
}

/**
* 处理附件路径信息
*/
export function handleFilePath(data, _this = null, isArray = false) {
  if (_this === null) { // 处理成字符串
      if (data && data instanceof Array) {
          return data.map(item => {
              if (item.real_path) {
                  return '/storage/' + item.real_path
              } else if (item.id && item.path) {
                  return '/storage/' + item.path.split('/storage/')[1]
              } else {
                  return item.path.split('.com')[1]
              }
          }).join(',')
      } else if (data.real_path) {
          return '/storage/' + data.real_path
      } else if (data.path) {
          return '/storage/' + data.path.split('/storage/')[1]
      } else {
          return ''
      }
  } else { // 组装成数组或对象
      if (isArray === false) {
          const result = {}
          if (data) {
              result.path = replaceAll(_this.BASE_API + data, ['//storage'], '/storage')
              result.suffix = data.substring(data.lastIndexOf('.') + 1)
          }
          return result
      } else {
          const result = []
          if (data) {
              result.push(...data.split(',').map(path => {
                  return {
                      path: replaceAll(_this.BASE_API + path, ['//storage'], '/storage'),
                      suffix: path.substring(path.lastIndexOf('.') + 1)
                  }
              }))
          }
          return result
      }
  }
}

/**
* 远程获取附件信息
*/
// export async function handleAttachmentInfos(pathStr, _this) {
//   const files = []
//   const fileInfos = {}
//   if (pathStr) {
//       let paths = Array.from(new Set(pathStr.split(','))) // 去重
//       paths = paths.map(path => {
//           return path.split('storage/')[1]
//       })
//       await apiAttachment.getAttachmentsInfos({ real_paths: paths.join(',') }).then(res => {
//           res.data.forEach(file => {
//               fileInfos[file.real_path] = file
//           })
//           paths.forEach(path => {
//               if (fileInfos[path]) {
//                   files.push(fileInfos[path])
//               } else {
//                   files.push({
//                       filename: path.split('/').splice(-1, 1)[0],
//                       path: handleFilePath('/storage/' + path, _this, false).path,
//                       suffix: path.substring(path.lastIndexOf('.') + 1)
//                   })
//               }
//           })
//       })
//   }

//   return { files, fileInfos }
// }

/**
* 处理导出表格的表头及数据
*/
export function handleFormatJson(keys, dataList) {
  return dataList.map(item => keys.map(key => {
      return item[key]
  }))
}

/**
* 处理附件路径
*/
export function replaceFilePath(path) {
  return replaceAll(path, ['api/down?file=', 'down?file='], 'storage/')
}

/**
* 处理排序
*/
export function handleOrderSort(list, reset = true) {
  list.sort((a, b) => {
      return a.order - b.order
  })
  if (reset) {
      list.forEach((item, index) => {
          item.order = index
      })
  }

  return list
}

/**
* 处理订单基础数据，返回对象
*/
export function handleOrderBaseData(order) {
  const result = {
      buyer_name: '',
      product_name: '',
      unit_weight: convertWeight(order.product_items[0].weight, 't', false), // 单位商品重量，单位：吨
      weight: 0, // 订单重量，单位：吨
      ton_price: 0, // 单位：元
      total_amount: 0, // 单位：元
      topay_type: '' // 付款方式
  }
  result.buyer_name = order.buyer.name
  const product = order.product_items[0]
  let unit_price = product.unit_price
  if (product.actual_unit_price) {
      unit_price = product.actual_unit_price
  }
  result.product_name = product.title

  let weight = 0
  order.product_items.forEach(item => {
      weight += item.buy_num * item.weight
  })
  result.weight = convertWeight(weight, 't', false)
  result.ton_price = convertCurrency(convertTonPrice(unit_price, product.weight), false)
  result.total_amount = convertCurrency(order.pay_price, false)
  result.topay_type = handleTopayType(order)

  return result
}

/**
* 处理审批申请摘要内容
*/
export function handleFieldAbstract(meta) {
  const abstract = []
  if (meta && meta.data) {
      abstract.push(...handleField(meta.data))
  } else if (meta && meta instanceof Array) {
      if (meta[0] instanceof Array) {
          meta.forEach(_meta => {
              if (_meta instanceof Array) {
                  abstract.push(...handleField(_meta))
              }
          })
      } else {
          abstract.push(...handleField(meta))
      }
  } else if (meta && meta.group) {
      if (meta.group instanceof Array) {
          meta.group.forEach(group => {
              abstract.push(...handleField(group))
          })
      } else {
          Object.keys(meta.group).forEach(key => {
              abstract.push(...handleField(meta.group[key]))
          })
      }

      if (meta.global) {
          abstract.push(...handleField(meta.global))
      }
  } else if (meta && meta instanceof Object) {
      Object.keys(meta).forEach(key => {
          abstract.push(...handleField(meta[key]))
      })
  }

  return abstract

  function handleField(list) {
      const _abs = []
      list.forEach(item => {
          let _value = ''
          if (/^\[:{1}\S+:\]{1}$/.test(item.value)) {
              const valueArr = item.value.substring(2, item.value.length - 2).split('|')
              const type = valueArr[0]
              const value = valueArr[1]
              if (type === 'currency') {
                  _value = numberFormat(convertCurrency(value, false))
              } else if (type === 'number') {
                  _value = numberFormat(value)
              } else if (type === 'weight') {
                  _value = numberFormat(convertWeight(value, 't', false))
              }
          } else if (typeof item.value === 'string' && (item.value.indexOf('http') > -1 || item.value.indexOf('storage') > -1)) {
              // 不做处理
          } else if (typeof item.value !== 'string' || item.value.indexOf('{"type"') === 0) {
              // 不做处理
          } else if (![null, undefined].includes(item.value)) {
              if (item.value.length > 100) {
                  _value = `${item.value.substr(0, 100)}...`
              } else {
                  _value = item.value
              }
          }

          if (_value !== '') {
              _abs.push(`${item.label}：${_value}`)
          }
      })

      return _abs
  }
}

/**
* 处理结算方式
*/
export function handleTopayType(info) {
  if (!info) return ''
  let value = ''
  if (info.topay_type) {
      if (info.topay_type instanceof Object) {
          value = info.topay_type.label
      } else if (typeof info.topay_type === 'string') {
          value = info.topay_type
      }
  }
  if (info.payment_days !== undefined) {
      ['**', 'XX'].forEach(symbol => {
          if (value.indexOf(symbol) > -1) {
              value = value.replace(symbol, info.payment_days)
          }
      })
  }
  return value
}
